#include <Wire.h>
#include <SPI.h>

/* Include BMP280 */
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp;

/* Some BMP reader functions */
float
read_bmp_temperature ()
{
  return bmp.readTemperature();
}

float
read_bmp_pressure ()
{
  return bmp.readPressure();
}

float
read_bmp_altitude ()
{
  return bmp.readAltitude();
}

/* Include AHTX0 */
#include <Adafruit_AHTX0.h>
Adafruit_AHTX0  aht;
sensors_event_t aht_humidity, aht_temp;

/* Some AHT reader functions. */
float
read_aht_temperature ()
{
  return aht_temp.temperature;
}

float
read_aht_humidity ()
{
  return aht_humidity.relative_humidity;
}

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH   128
#define SCREEN_HEIGHT  32

#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // See datasheet for Address; 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

<<display-process-functions>>

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebSrv.h>

#define SERVER_PORT 80
AsyncWebServer server(SERVER_PORT);

#define TEMPERATURE 0
#define PRESSURE    1
#define ALTITUDE    2
#define HUMIDITY    3

int pane_state = TEMPERATURE;

void
setup ()
{
  bmp.begin();
  bmp.setSampling(
                  Adafruit_BMP280::MODE_NORMAL,
                  Adafruit_BMP280::SAMPLING_X16,
                  Adafruit_BMP280::SAMPLING_X16,
                  Adafruit_BMP280::FILTER_X16,
                  Adafruit_BMP280::STANDBY_MS_500
                  );

  /* Init AHT */
  aht.begin();
  aht.getEvent(&aht_humidity, &aht_temp);

  display.begin();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  
  // Clear Display Buffer and refresh screen
  display.clearDisplay();
  display.display();

  // Log in WiFi
  const char* ssid     = "WIFI 名称";
  const char* password = "WIFI 密码";
  WiFi.begin(ssid, password);
  
  // Root Page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      sensors_event_t humidity, temp;
      aht.getEvent(&humidity, &temp);
  
      request->send(200,
                    "text/plain", 
                    "TEMP(AHT): " + String(read_aht_temperature(), 4) + " *C\n" +
                    "TEMP(BMP): " + String(read_bmp_temperature(), 4) + " *C\n" +
                    "HUMIDITY: " +  String(read_aht_humidity(), 4)    + " %rH\n" +
                    "PRESSURE: " +  String(read_bmp_pressure(), 6)    + " Pa\n" +
                    "ALTITUDE: " +  String(read_bmp_altitude(), 4)    + " M\n" +
                    "::============== ryo ==============::\n");
    });
  
  // Server on 404
  server.onNotFound([](AsyncWebServerRequest *request){
      request->send(404,
                    "text/plain",
                    String("You are now at no man's land.\n") +
                    String("::============== ryo ==============::\n"));
    });
  
  server.begin();
}

void
loop ()
{
  // every display_* function should last for a while
  switch (pane_state) {
  case TEMPERATURE : display_temperature(); break;
  case PRESSURE    : display_pressure();    break;
  case ALTITUDE    : display_altitude();    break;
  case HUMIDITY    : display_humidity();    break;
  default          : display_temperature(); break;
  }

  pane_state = (pane_state + 1) % 4;
}
